const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const moment = require('moment');

// 日志目录
const LOG_DIR = path.join(__dirname, 'logs');

// 确保日志目录存在
if (!fs.existsSync(LOG_DIR)) {
    fs.mkdirSync(LOG_DIR, { recursive: true });
}

// 日志文件路径
function getLogFilePath() {
    const date = moment().format('YYYY-MM-DD');
    return path.join(LOG_DIR, `watchdog_${date}.log`);
}

// 写入日志
function writeLog(message) {
    const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
    const logMessage = `[${timestamp}] ${message}\n`;
    
    console.log(logMessage.trim());
    
    fs.appendFileSync(getLogFilePath(), logMessage);
}

// 监控的文件列表
const watchFiles = [
    'server.js',
    'soapService.js',
    'dbSync.js',
    'scheduler.js'
];

// 文件修改时间缓存
let fileModifiedTimes = {};

// 初始化文件修改时间
function initFileModifiedTimes() {
    watchFiles.forEach(file => {
        try {
            const stats = fs.statSync(file);
            fileModifiedTimes[file] = stats.mtime.getTime();
        } catch (error) {
            writeLog(`无法获取文件 ${file} 的修改时间: ${error.message}`);
        }
    });
}

// 检查文件是否已更新
function checkFilesUpdated() {
    let updated = false;
    let updatedFiles = [];
    
    watchFiles.forEach(file => {
        try {
            const stats = fs.statSync(file);
            const currentMTime = stats.mtime.getTime();
            
            if (fileModifiedTimes[file] && currentMTime > fileModifiedTimes[file]) {
                updated = true;
                updatedFiles.push(file);
                fileModifiedTimes[file] = currentMTime;
            }
        } catch (error) {
            writeLog(`检查文件 ${file} 时出错: ${error.message}`);
        }
    });
    
    if (updated) {
        writeLog(`检测到文件更新: ${updatedFiles.join(', ')}`);
    }
    
    return updated;
}

// 启动服务器进程
function startServer() {
    writeLog('启动服务器进程...');
    
    // 使用 node 命令启动 server.js
    const server = spawn('node', ['server.js'], {
        stdio: ['ignore', 'pipe', 'pipe'],
        detached: false
    });
    
    // 服务器进程ID
    const pid = server.pid;
    writeLog(`服务器进程已启动，PID: ${pid}`);
    
    // 标准输出
    server.stdout.on('data', (data) => {
        process.stdout.write(data);
    });
    
    // 标准错误
    server.stderr.on('data', (data) => {
        process.stderr.write(data);
    });
    
    // 进程退出
    server.on('exit', (code, signal) => {
        if (code !== null) {
            writeLog(`服务器进程退出，退出码: ${code}`);
        } else {
            writeLog(`服务器进程被信号 ${signal} 终止`);
        }
        
        // 延迟重启服务器
        setTimeout(() => {
            writeLog('正在重启服务器...');
            startServerWithWatchdog();
        }, 3000);
    });
    
    return server;
}

// 带有监控功能的服务器启动
function startServerWithWatchdog() {
    // 初始化文件修改时间
    initFileModifiedTimes();
    
    // 启动服务器
    const server = startServer();
    
    // 设置文件监控定时器（每5秒检查一次）
    const watchTimer = setInterval(() => {
        if (checkFilesUpdated()) {
            writeLog('检测到代码更新，正在重启服务器...');
            
            // 杀掉当前服务器进程
            if (server.pid) {
                writeLog(`正在终止服务器进程 (PID: ${server.pid})...`);
                
                // Windows平台使用taskkill强制终止进程
                if (process.platform === 'win32') {
                    spawn('taskkill', ['/pid', server.pid, '/f', '/t']);
                } else {
                    // Unix平台使用kill信号
                    process.kill(server.pid, 'SIGTERM');
                }
                
                // 清除当前的监控定时器
                clearInterval(watchTimer);
            }
        }
    }, 5000);
    
    // 处理守护进程自身的退出
    process.on('SIGINT', () => {
        writeLog('收到中断信号，正在终止所有进程...');
        
        // 杀掉服务器进程
        if (server.pid) {
            writeLog(`正在终止服务器进程 (PID: ${server.pid})...`);
            
            if (process.platform === 'win32') {
                spawn('taskkill', ['/pid', server.pid, '/f', '/t']);
            } else {
                process.kill(server.pid, 'SIGTERM');
            }
        }
        
        // 清除监控定时器
        clearInterval(watchTimer);
        
        // 延迟退出，确保日志写入
        setTimeout(() => {
            writeLog('守护进程正在退出');
            process.exit(0);
        }, 1000);
    });
}

// 打印启动信息
writeLog('====================================');
writeLog('服务器守护进程启动');
writeLog(`监控文件: ${watchFiles.join(', ')}`);
writeLog('====================================');

// 启动带有监控功能的服务器
startServerWithWatchdog(); 